package top.jle.spring.basic.api;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import top.jle.jpa.basic.exception.BasicCustomException;
import top.jle.jpa.basic.exception.BasicExceptionCode;
import top.jle.spring.basic.annotation.PassToken;

import java.util.Map;
import java.util.Optional;

@RestController
@Hidden
@EnableConfigurationProperties({ServerProperties.class})
@Slf4j
public class APIErrorHandler extends BasicErrorController {

    private static final String EXCEPTION_MESSAGE_KEY = "message";
    /**
     * 必须实现的一个构造方法
     **/
    public APIErrorHandler() {
        super(new DefaultErrorAttributes(), new ErrorProperties());
    }


    @Override
    @PassToken
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request){
        Map<String, Object> body = getErrorAttributes(request, ErrorAttributeOptions.of(ErrorAttributeOptions.Include.EXCEPTION, ErrorAttributeOptions.Include.MESSAGE));
        log.error("errorHandler cache error:{}",JSONObject.toJSONString(body));
        HttpStatus status = getStatus(request);
        ResponseBack<String> back =  ResponseBack.error(new Exception());
        back.setCode(body.get("status").toString());
        back.setResult(null);
        back.setResult(Optional.ofNullable(body.get(EXCEPTION_MESSAGE_KEY)).orElseGet(()->body.get("error")).toString());
        String exception = Optional.ofNullable(body.get("exception")).orElse("").toString();
        if(exception.equals(BasicCustomException.class.getName())){
            try {
                JSONObject exceptionInfo = JSONObject.parseObject(body.get(EXCEPTION_MESSAGE_KEY).toString());
                back.setCode(exceptionInfo.getString("code"));
                back.setResult(exceptionInfo.getString(EXCEPTION_MESSAGE_KEY));
            }catch (Exception e){
                back.setCode(body.get(EXCEPTION_MESSAGE_KEY).toString());
            }

        }else{
            back.setCode(BasicExceptionCode.SERVER_ERROR.getCode());
        }
        return new ResponseEntity<>((JSONObject) JSON.toJSON(back), status);
    }
}
